// Copyright 2025 祝灵福
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { ArgumentsHost, Catch, ExceptionFilter, HttpException, LoggerService } from '@nestjs/common'
import { Response } from 'express' // 导入 Express 的 Response 类型
import { Request } from 'express' // 导入 Express 的 Request 类型

@Catch(HttpException) //定义并处理特定类型的异常，使得框架可以根据异常类型采取适当的处理逻辑，提供一致的错误响应机制。
// @Catch() 如果不传入任何参数，表示该过滤器会捕获应用程序中的所有异常类型，可以用来实现通用的全局异常处理
export class HttpExceptionFilter implements ExceptionFilter {
  // 记录到日志里
  constructor(private logger: LoggerService) {}
  //exception：捕获的异常对象，在这里是 HttpException 类型的异常。host: 包含请求和响应上下文的信息
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp() // HTTP 请求上下文。
    const response = ctx.getResponse<Response>() //获取 HTTP 响应对象。
    // const request = ctx.getRequest<Request>() //获取 HTTP 请求对象
    const status = exception.getStatus() //获取 HTTP 异常的状态码
    // 记录错误日志exception.message：是异常对象的消息部分exception.stack：是异常的堆栈信息，它提供了错误发生的位置和调用栈的跟踪，有助于定位问题的具体位置。
    this.logger.error(exception.message, exception.stack)
    response.status(status).json({
      //使用 response 对象返回一个自定义的错误响应。该响应是一个 JSON 格式的对象
      code: status, //状态码，等于捕获的异常的状态码
      timeStamp: new Date().toISOString(), //当前时间戳，表示响应的时间
      //   因为exception.message提供了path和method，所以被注释了
      //   path: request.url, //请求的 URL 路径
      //   method: request.method, //请求的方法（如 GET、POST）。
      message: exception.message || HttpException.name //异常的消息，默认为异常的 message 或者 HttpException.name
    })
    // throw new Error('Method not implemented.')
  }
}
